import java.util.ArrayList;
import java.util.List;
import ar.uba.fi.algo3.titiritero.Dibujable;
import ar.uba.fi.algo3.titiritero.Posicionable;
import ar.uba.fi.algo3.titiritero.SuperficieDeDibujo;

public class Laberinto implements Dibujable{
	
	private int dificultad;
	private Matriz matriz;
	private int puntaje;
	private boolean power;
	private int vidas;
	private List listaFantasmas;
	private Pacman pacman;
	private Punto dimension;	
	
	public int getVidas() {
		return vidas;
	}

	public void setVidas(int vidas) {
		this.vidas = vidas;
	}

	public Laberinto(){
		
		pacman = new Pacman();
		inicializarListaFantasmas();
		this.matriz = new Matriz(Constantes.ANCHO_TABLERO, Constantes.ALTURA_TABLERO);
		this.dimension = new Punto(Constantes.ANCHO_TABLERO, Constantes.ALTURA_TABLERO);
		this.puntaje = 0;
		this.vidas = 3;
	}
	
	private void inicializarListaFantasmas(){
		
		Fantasma blinky = new Blinky();
		Fantasma pinky = new Pinky();
		Fantasma inky = new Inky();
		Fantasma clide = new Clide();
		
		listaFantasmas = new ArrayList(4);
		
		listaFantasmas.add(0, blinky);
		listaFantasmas.add(1, pinky);
		listaFantasmas.add(2, inky);
		listaFantasmas.add(3, clide);
	}
	
	public Celda getCelda(Punto posicion){
		return matriz.get(posicion);
	}
	
	public void setCelda(Celda celda){
		
		matriz.set(celda.getPosicion(), celda);
	}
	
	public Punto getPosicionBlinky(){
		
		Fantasma blinky = (Fantasma)listaFantasmas.get(0);
		return blinky.getPosicion();
	}
	
	public Punto getPosicionPacman(){	
		return pacman.getPosicion();
	}
	public void setPosicionPacMan(Punto nuevaPosPacMan) {
		pacman.setPosicion(nuevaPosPacMan);
	}
	
	public Punto obtenerNuevaPosicionSegunDireccion(int direccion, Punto posicionActual){
		
		switch (direccion) {
		case Constantes.DIRECC_ARRIBA:
			return posicionActual.moverArriba();
		case Constantes.DIRECC_ABAJO: 
			return posicionActual.moverAbajo();
		case Constantes.DIRECC_IZQUIERDA: 
			return posicionActual.moverIzquierda();
		case Constantes.DIRECC_DERECHA:
			return posicionActual.moverDerecha();
		case Constantes.DIRECC_OPUESTA:
			return posicionActual.moverOpuesto();
		default:
			return null;
		}
	}

	public void sumarPuntos(int puntos) {
		
		this.puntaje = puntaje + puntos;
	}

	public void reiniciarFantasma(Fantasma unFantasma) {
		
		unFantasma.setPosicion(Constantes.POSICION_INICIAL_FANTASMA);
		unFantasma.setEscapar(false);
		
	}
	
	public void reiniciarListaFantasmas(){
		
		List fantasmas = this.getListaFantasmas();
		for (int i = 0; i < fantasmas.size(); i++) {
			Fantasma fantasma = (Fantasma)fantasmas.get(0);
			reiniciarFantasma(fantasma);
		}
	}

	public int getPuntaje() {
		return puntaje;
	}

	public void cambiarEstadoJuego() {
		
		for (int i = 0; i < listaFantasmas.size(); i++) {
			
			Fantasma fantasma = (Fantasma)listaFantasmas.get(i);
			fantasma.setEscapar(true);
			fantasma.setMovimientoEscapar();
			
		}
	}
	
	public int calcularDistancia(Punto unPunto, Punto otroPunto){
		
		return Math.abs(unPunto.getX() - otroPunto.getX()) 
					+ Math.abs(unPunto.getY() - otroPunto.getY()); 
	}

	public boolean estaEnPersecucion() {
		
		return this.power;
	}

	public void muertePacman() {
		this.vidas = vidas - 1;
		pacman = new Pacman();
		this.reiniciarListaFantasmas();
	}
	
	public void agregarFantasma(Fantasma fantasma){
		
		listaFantasmas.add(fantasma);
	}
	
	
	/**
	 * Ordena las celdas posibles a mover por orden de proximidad a un objetivo
	 * @param celdas
	 * @param target
	 * @return array de celdas ordenadas
	 */
	public ArrayList ordenarCeldasPorProximidad(ArrayList celdas, Punto target){
		
		ArrayList celdasOrdenadas = new ArrayList();
		Celda celda1 = (Celda)celdas.get(0);
		Celda celda2 = (Celda)celdas.get(1);
		Celda celda3 = (Celda)celdas.get(2);
		
		Punto pos1 = celda1.getPosicion();
		Punto pos2 = celda2.getPosicion();
		Punto pos3 = celda3.getPosicion();
		
		int dist1 = this.calcularDistancia(target, pos1);
		int dist2 = this.calcularDistancia(target, pos2);
		int dist3 = this.calcularDistancia(target, pos3);
		
		if((dist1 <= dist2) && (dist2 <= dist3)){
			celdasOrdenadas.add(celda1);
			celdasOrdenadas.add(celda2);
			celdasOrdenadas.add(celda3);
		}else if((dist1 <= dist3) && (dist3 <= dist2)){
			celdasOrdenadas.add(celda1);
			celdasOrdenadas.add(celda3);
			celdasOrdenadas.add(celda2);
		}else if((dist2 <= dist1) && (dist1 <= dist3)){
			celdasOrdenadas.add(celda2);
			celdasOrdenadas.add(celda1);
			celdasOrdenadas.add(celda3);
		}else if((dist2 <= dist3) && (dist3 <= dist1)){
			celdasOrdenadas.add(celda2);
			celdasOrdenadas.add(celda3);
			celdasOrdenadas.add(celda1);
		}else if((dist3 <= dist1) && (dist1 <= dist2)){
			celdasOrdenadas.add(celda3);
			celdasOrdenadas.add(celda1);
			celdasOrdenadas.add(celda2);
		}else if((dist3 <= dist2) && (dist2 <= dist1)){
			celdasOrdenadas.add(celda3);
			celdasOrdenadas.add(celda2);
			celdasOrdenadas.add(celda1);
		}	
		
		return celdasOrdenadas;
	}

	private int getDireccionPacman() {
		return this.pacman.getDireccion();		
	}
	
	public Punto buscarObjetivoAlternativoPinky() {
		int x = 0;
		int y = 0;
		Punto target = new Punto(x, y);
		Punto posicionPacman = this.getPosicionPacman();
		int direccionPacman = this.getDireccionPacman();
		
		switch(direccionPacman){
		
		case 1: //ARRIBA
			x = posicionPacman.getY();
			y = posicionPacman.getX()+4;
			
		case 2: //ABAJO
			x = posicionPacman.getY();
			y = posicionPacman.getX()-4;
			
		case 3: // IZQUIERDA
			x = posicionPacman.getY()-4;
			y = posicionPacman.getX();
			
		case 4: //DERECHA
			x = posicionPacman.getY()+4;
			y = posicionPacman.getX();
		}
		
		target.setX(x);
		target.setY(y);
		
		return target;	
	}

	public Punto buscarObjetivoAlternativoInky() {
		
		Punto target;
		Punto posicionPacman = this.getPosicionPacman();
		Punto posicionBlinky = this.getPosicionBlinky();
		int x = 0;
		int y = 0;
		int res1 = Math.abs(posicionBlinky.getX() - posicionPacman.getX());
		int res2 = Math.abs(posicionBlinky.getY() - posicionPacman.getY());
	
		if(Math.abs(posicionBlinky.getX()) < Math.abs(posicionPacman.getX())){
			x = Math.abs(posicionPacman.getX()) + res1;
		}else{
			x = Math.abs(posicionPacman.getX()) - res1;
		}
		if(Math.abs(posicionBlinky.getY()) < Math.abs(posicionPacman.getY())){
			y = Math.abs(posicionPacman.getY()) + res2;
		}else{
			y = Math.abs(posicionPacman.getY()) - res2;
		}
		
		target = new Punto(x,y);
		return target;
	}

	public List getListaFantasmas() {
		return listaFantasmas;
	}

	public Punto getDimension() {
		return dimension;
	}

	public void dibujar(SuperficieDeDibujo superfice) {
		// TODO Auto-generated method stub
		
	}

	public Posicionable getPosicionable() {
		// TODO Auto-generated method stub
		return null;
	}

	public void setPosicionable(Posicionable posicionable) {
		// TODO Auto-generated method stub
		
	}

	public Pacman getPacman() {
		return this.pacman;
	}

}
